
// 13.33 in 802.1Q-2005

#include "802_1Q_2005_procedures.h"
#include "bridge.h"
#include "port.h"
#include "assert.h"

enum
{
	UNDEFINED,
	INIT_TREE,
	ROLE_SELECTION,
};

// ============================================================================

const char* PortRoleSelection_802_1Q_2005_GetStateName (SM_STATE state)
{
	switch (state)
	{
		case INIT_TREE:		return "INIT_TREE";
		case ROLE_SELECTION:return "ROLE_SELECTION";
		default:			return "(undefined)";
	}
}

// ============================================================================

SM_STATE PortRoleSelection_802_1Q_2005_CheckConditions (BRIDGE* bridge, int givenPort, int givenTree, SM_STATE state)
{
	assert (givenTree != -1);
	assert (givenPort == -1);

	// ------------------------------------------------------------------------
	// Check global conditions.
	
	if (bridge->BEGIN)
	{
		if (state == INIT_TREE)
		{
			// The entry block for this state has been executed already.
			return 0;
		}
		
		return INIT_TREE;
	}
	
	// ------------------------------------------------------------------------
	// Check exit conditions from each state.
	
	if (state == INIT_TREE)
		return ROLE_SELECTION;
	
	if (state == ROLE_SELECTION)
	{
		for (int portIndex = 0; portIndex < bridge->portCount; portIndex++)
		{
			if (bridge->ports [portIndex]->trees [givenTree]->reselect)
				return ROLE_SELECTION;
		}
		
		return 0;
	}

	assert (false);
	return 0;
}

// ============================================================================

void PortRoleSelection_802_1Q_2005_InitState (BRIDGE* bridge, int givenPort, int givenTree, SM_STATE state)
{
	assert (givenTree != -1);
	assert (givenPort == -1);

	if (state == INIT_TREE)
	{
		updtRolesDisabledTree (bridge, givenTree);
	}
	else if (state == ROLE_SELECTION)
	{
		clearReselectTree (bridge, givenTree);
		updtRolesTree (bridge, givenTree);
		setSelectedTree (bridge, givenTree);
	}
	else
		assert (false);
}
